with ada.text_io;
with ada.characters.handling;
use ada.characters.handling;

procedure assg1 is

    subtype buffer is String (Integer range 1..256);

    package t_io renames ada.text_io;

    function decode (to_decode : Character; key : Character) return Character is
	keyOffset, low : Natural;
	letter : Integer;
    begin
	keyOffset := Character'pos ( to_upper (key) ) - Character'pos ('A');

	if is_upper (to_decode) then
	    low := Character'pos ('A');
	else
	    low := Character'pos ('a');
	end if;
	
	letter := (Character'pos (to_decode) - low - keyOffset) mod 26;

	return Character'val (low + letter);
    end decode;

    key, filename : buffer;
    key_length : Natural;
    key_index : Natural;
    file_length : Natural;
    in_f, out_f : t_io.File_Type;
    c : Character;

begin

    t_io.put("Enter the Key to decode with  > ");
    t_io.get_line (key, key_length);

    t_io.put("Enter the name of the input file  > ");
    t_io.get_line (filename, file_length);
    t_io.open(in_f, t_io.In_File, filename(1..file_length));

    t_io.put("Enter the name of the output file  > ");
    t_io.get_line (filename, file_length);
    begin
	t_io.open(out_f, t_io.Out_file, filename(1..file_length));
    exception
	when t_io.name_error =>
	    t_io.create(out_f, t_io.Out_file, filename);
    end;

    key_index := 0;
    loop
	t_io.get(in_f, c);
	if is_letter(c) then
	    c := decode(c, key(key_index+1));
	    key_index := (key_index + 1) mod (key_length);
	end if;
	t_io.put(out_f, c);
	if t_io.end_of_line(in_f) then
	    t_io.new_line(out_f);
	
	end if;
	exit when t_io.end_of_file(in_f);
    end loop;

    t_io.close(in_f);
    t_io.close(out_f);
    t_io.put_line ("operations completed");
end assg1;
